project(RAP)

set(SAMPLE_NAME feature_preprocess)

# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-vectorize")

file(GLOB FLEXIOSOURCES ${CMAKE_SOURCE_DIR}/wrapper_flexio/*.cpp)
list(APPEND APP_ADDITIONAL_SOURCES ${FLEXIOSOURCES})

set(program_lib_name feature_device)
file(GLOB_RECURSE app_dev_source_file ${CMAKE_CURRENT_SOURCE_DIR}/device/*.c)
list(APPEND app_dev_source_file ${CMAKE_SOURCE_DIR}/wrapper_flexio/wrapper_flexio_device.c)

set(app_dev_build_dir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
# set(program_lib_include_dir 
#     -I${CMAKE_SOURCE_DIR}/wrapper_flexio
#     -I${CMAKE_CURRENT_SOURCE_DIR}/utils
# )

string(JOIN "," program_lib_include_dir
    "-I${CMAKE_SOURCE_DIR}/wrapper_flexio"
    "-I${CMAKE_CURRENT_SOURCE_DIR}/utils"
)

#set(program_user_lib -lflexio_dev)
# don't use link it
set(program_user_lib -ldoca_dpa_dev -ldoca_dpa_dev_comm)
set(dpacc_build_script ${CMAKE_SOURCE_DIR}/build_dpacc_samples.sh)

file(GLOB RAP_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/utils/*.cc)
file(GLOB PROTO_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/utils/proto/*.cc)

# add_executable(${SAMPLE_NAME} ./test/feature_deal.cpp ./utils/feature_cross.h ${RAP_UTILS} ${UTILSOURCES} ${APP_ADDITIONAL_SOURCES})

# target_include_directories(${SAMPLE_NAME} PUBLIC
#     ${CMAKE_CURRENT_SOURCE_DIR}/utils
#     # 其他子模块...
# )

find_package(OpenMP REQUIRED)
# target_link_libraries(${SAMPLE_NAME} ${app_dev_build_dir}/${program_lib_name}.a ${LIBRARIES} ibverbs mlx5 OpenMP::OpenMP_CXX)

# add brpc test program
find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
find_library(LEVELDB_LIB NAMES leveldb)
if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
    message(FATAL_ERROR "Fail to find leveldb")
endif()

find_package(OpenSSL)

find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(LINK_SO)
    find_library(BRPC_LIB NAMES brpc)
else()
    find_library(BRPC_LIB NAMES libbrpc.a brpc)
endif()
if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB))
    message(FATAL_ERROR "Fail to find brpc")
endif()

find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
    set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
    set(THRIFTNB_LIB "")
endif()

set(DYNAMIC_LIB
    ${CMAKE_THREAD_LIBS_INIT}
    ${GFLAGS_LIBRARY}
    ${PROTOBUF_LIBRARIES}
    ${LEVELDB_LIB}
    ${OPENSSL_CRYPTO_LIBRARY}
    ${OPENSSL_SSL_LIBRARY}
    ${THRIFT_LIB}
    ${THRIFTNB_LIB}
    glog
    dl
    )

set (CPU_TEST test_cpu)
add_executable(${CPU_TEST} ./test/test_cpu.cpp ${PROTO_UTILS} ${RAP_UTILS} ${UTILSOURCES} ${APP_ADDITIONAL_SOURCES})

set (CPU_TEST_SERVER test_cpu_server)
add_executable(${CPU_TEST_SERVER} ./test/test_cpu_server.cpp ${PROTO_UTILS} ${RAP_UTILS} ${UTILSOURCES} ${APP_ADDITIONAL_SOURCES})

add_custom_command(OUTPUT dpacc_${SAMPLE_NAME}
        COMMAND ${dpacc_build_script} ${program_lib_name} \"${app_dev_source_file}\" ${app_dev_build_dir} ${program_lib_include_dir} ${program_user_lib}
)
add_custom_target(
        dpacc_${SAMPLE_NAME}_target ALL
        DEPENDS dpacc_${SAMPLE_NAME}
)

add_dependencies(${CPU_TEST} dpacc_${SAMPLE_NAME}_target)
add_dependencies(${CPU_TEST_SERVER} dpacc_${SAMPLE_NAME}_target)

set(COMMON_LIBS
    ${LIBRARIES}
    ${DYNAMIC_LIB}
    ${BRPC_LIB}
    ${app_dev_build_dir}/${program_lib_name}.a
    ibverbs
    mlx5
    OpenMP::OpenMP_CXX
    profiler
)

# 定义公共链接目录变量
set(COMMON_LINK_DIRS
    "${compile_root}/glog-0.5.0/lib"
    "${compile_root}/libnl"
)

# 定义公共包含目录变量
set(COMMON_INCLUDES
    ${CMAKE_CURRENT_SOURCE_DIR}/utils
    ${CMAKE_CURRENT_SOURCE_DIR}/utils/proto
    ${LEVELDB_INCLUDE_PATH}
    ${OPENSSL_INCLUDE_DIR}
    ${BRPC_INCLUDE_PATH}
    "${compile_root}/glog-0.5.0/include"
)

foreach(target_name ${CPU_TEST} ${CPU_TEST_SERVER})  # 添加所有需要配置的目标
    if(TARGET ${target_name})
        target_link_libraries(${target_name} ${COMMON_LIBS})
        target_link_directories(${target_name} PUBLIC ${COMMON_LINK_DIRS})
        target_include_directories(${target_name} PUBLIC ${COMMON_INCLUDES})
    endif()
endforeach()

set (CONNECT_TEST_CLIENT test_communication_client)
add_executable(${CONNECT_TEST_CLIENT} ./test/test_communication_client.cpp ${PROTO_UTILS} ${RAP_UTILS} ${UTILSOURCES} ${APP_ADDITIONAL_SOURCES})

set (CONNECT_TEST_SERVER test_communication_server)
add_executable(${CONNECT_TEST_SERVER} ./test/test_communication_server.cpp ${PROTO_UTILS} ${RAP_UTILS} ${UTILSOURCES} ${APP_ADDITIONAL_SOURCES})

set (OPERATOR_TEST test_operator)
add_executable(${OPERATOR_TEST} ./test/test_operator.cpp ${PROTO_UTILS} ${RAP_UTILS} ${UTILSOURCES} ${APP_ADDITIONAL_SOURCES})

set (KV_TEST kv_server)
add_executable(${KV_TEST} ./test/kv_server.cpp ${PROTO_UTILS} ${RAP_UTILS} ${UTILSOURCES} ${APP_ADDITIONAL_SOURCES})

foreach(target_name ${CONNECT_TEST_CLIENT} ${CONNECT_TEST_SERVER} ${OPERATOR_TEST} ${KV_TEST})  # 添加所有需要配置的目标
    if(TARGET ${target_name})
        target_link_libraries(${target_name} ${COMMON_LIBS})
        target_link_directories(${target_name} PUBLIC ${COMMON_LINK_DIRS})
        target_include_directories(${target_name} PUBLIC ${COMMON_INCLUDES})
    endif()
endforeach()